/*
 ============================================================================
 Name        : BufferSCM.c
 Author      :
 Version     :
 Copyright   : 
 Description :
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>

float totalOperations;
float totalWriteOperationsPercent;
float totalReadOperations;
float totalWriteOperations;
float totalReadOperationsRemaining;
float totalWriteOperationsRemaining;
char opType;
int i, pageId, totalPages;

float getTotalOperations(float totalOperations, float totalWriteOperationsPercent, char operationType){
        float totalWriteOperations=totalOperations*(totalWriteOperationsPercent/100);
        float totalReadOperations=totalOperations-totalWriteOperations;
        if(operationType=='W'){
        		return round(totalWriteOperations);
        	}else if(operationType=='R'){
        		return round(totalReadOperations);
        	}
}



char getOperationType(int writeAffinity){
	if( (writeAffinity==25) || (writeAffinity==50) || (writeAffinity==75) ){

		return 'W';

		/*
		int random=getRandomNumber(0,100000,2);

		if(writeAffinity==25){
			if( (random>=0) && (random<=25000) ){

			}
			return round(totalReadOperations);
		}*/
	}


}

int random_in_range (unsigned int min, unsigned int max)
{
  int base_random = rand(); /* in [0, RAND_MAX] */
  if (RAND_MAX == base_random) return random_in_range(min, max);
  /* now guaranteed to be in [0, RAND_MAX) */
  int range       = max - min,
      remainder   = RAND_MAX % range,
      bucket      = RAND_MAX / range;
  /* There are range buckets, plus one smaller interval
     within remainder of RAND_MAX */
  if (base_random < RAND_MAX - remainder) {
    return min + base_random/bucket;
  } else {
    return random_in_range (min, max);
  }
}

unsigned int randr(unsigned int min, unsigned int max)
{
       double scaled = (double)rand()/RAND_MAX;
       return (max - min +1)*scaled + min;
}


int getRandomNumber(int minRange, int maxRange,int codRandomGenerator){
	switch (codRandomGenerator){
	case 1:
		return randr(minRange,maxRange);
		break;
	case 2:
		return random_in_range(minRange,maxRange);
		break;
	}
}


int generateOperations(void) {

	// Initialize Variables
	totalOperations=10;
	totalWriteOperationsPercent=75;
	totalPages=1000;
	totalWriteOperations=getTotalOperations(totalOperations,totalWriteOperationsPercent,'W');
	totalReadOperations=getTotalOperations(totalOperations,totalWriteOperationsPercent,'R');
	totalReadOperationsRemaining=totalReadOperations;
	totalWriteOperationsRemaining=totalWriteOperations;


	// Generating Operations
	for(i=0;i<=totalOperations;i++){

		if( (totalReadOperationsRemaining==0) && (totalWriteOperationsRemaining==0) ){
			return EXIT_SUCCESS;
		}

		opType=getOperationType(totalWriteOperationsPercent);
		pageId=getRandomNumber(0,totalPages,2);

		if(totalReadOperationsRemaining==0){
			opType='W';
		} else if(totalWriteOperationsRemaining==0){
			opType='R';
		}

		if(opType=='R'){
			totalReadOperationsRemaining--;
			// return opType;
		}else if(opType=='W'){
			totalWriteOperationsRemaining--;
			// return opType;
		}

		puts("-----------------------------------------");
		printf("Operation Type: %c\n",opType);
		printf("Selected Page Id: %i\n",pageId);
		puts("-----------------------------------------");
		printf("Total Write Operations: %i\n",(int)totalWriteOperations);
		printf("Total Read Operations: %i\n",(int)totalReadOperations);
		puts("-----------------------------------------");
		printf("Total Write Operations Remaining: %i\n",(int)totalWriteOperationsRemaining);
		printf("Total Read Operations Remaining: %i\n",(int)totalReadOperationsRemaining);
		puts("========================================================================\n\n\n");

	}

	return EXIT_SUCCESS;

}


int main(void) {
	generateOperations();
}
